package com.flyqiu.form.api.tools;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.flyqiu.common.tools.FlyQiuCollectionTools;
import com.flyqiu.form.common.col.SqlColType;
import com.flyqiu.form.model.avue.AvueBaseFormColumn;
import com.flyqiu.form.model.entity.FlyQiuTableConfig;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public class FlyQiuAvueColTools {

    /**
     * 创建列信息
     *
     * @param prop        被追加字段：名称
     * @param label       被追加字段：中文名称
     * @param sqlDataType 被追加字段：数据类型（数据库数据类型）
     * @param size        被追加字段：数据长度（数据库数据长度）
     * @param precision   被追加字段：数据精度（数据库数据精度）
     * @return {@link  AvueBaseFormColumn}
     */
    public static AvueBaseFormColumn createColumn(String prop, String label, String sqlDataType, Integer size, Integer precision) {
        AvueBaseFormColumn columnColumn = new AvueBaseFormColumn();
        columnColumn.setLabel(label);
        columnColumn.setProp(prop);
        columnColumn.setSqlDataType(sqlDataType);
        columnColumn.setSqlDataLength(size);
        if (size != null && precision != null && precision > 0) {
            columnColumn.setPrecision(precision);
        }
        columnColumn.setAddDetail(false);
        columnColumn.setAddDisplay(false);
        columnColumn.setEditDetail(false);
        columnColumn.setEditDisplay(false);
        columnColumn.setHide(true);
        columnColumn.setDisplay(false);
        return columnColumn;
    }

    /**
     * 自动追加系统默认列信息
     *
     * @param colMap 当前列信息map
     * @param column 当前正在操作的列信集合
     * @param prop   被追加字段：名称
     * @param label  被追加字段：中文名称
     * @param type   被追加字段：数据类型（数据库数据类型）
     */
    public static void autoAppendField(Map colMap, JSONArray column, String prop, String label, String type) {
        autoAppendField(colMap, column, prop, label, type, null, null);
    }

    /**
     * 自动追加系统默认列信息
     *
     * @param colMap 当前列信息map
     * @param column 当前正在操作的列信集合
     * @param prop   被追加字段：名称
     * @param label  被追加字段：中文名称
     * @param type   被追加字段：数据类型（数据库数据类型）
     * @param size   被追加字段：数据长度（数据库数据长度）
     */
    @SuppressWarnings("unchecked")
    public static void autoAppendField(Map colMap, JSONArray column, String prop, String label, String type, Integer size) {
        autoAppendField(colMap, column, prop, label, type, size, null);
    }

    @SuppressWarnings("unchecked")
    public static void autoAppendField(Map colMap, JSONArray column,
                                       String prop,
                                       String label,
                                       String type, Integer size, Integer appendIndex) {
        autoAppendField(colMap, column, prop, label, type, size, null, appendIndex);
    }

    public static void autoAppendField(Map colMap, JSONArray column,
                                       String prop,
                                       String label,
                                       SqlColType sqlColType) {
        Integer precision = sqlColType.getPrecision();
        String sqlDataType = sqlColType.getSqlDataType();
        Integer sqlDataLength = sqlColType.getSqlDataLength();
        autoAppendField(colMap, column, prop, label, sqlDataType, sqlDataLength, precision, null);
    }

    public static void autoAppendField(Map colMap, JSONArray column,
                                       String prop,
                                       String label,
                                       SqlColType sqlColType, Integer appendIndex) {
        Integer precision = sqlColType.getPrecision();
        String sqlDataType = sqlColType.getSqlDataType();
        Integer sqlDataLength = sqlColType.getSqlDataLength();
        autoAppendField(colMap, column, prop, label, sqlDataType, sqlDataLength, precision, appendIndex);
    }


    /**
     * 自动追加系统默认列信息
     *
     * @param colMap      当前列信息map
     * @param column      当前正在操作的列信集合
     * @param prop        被追加字段：名称
     * @param label       被追加字段：中文名称
     * @param type        被追加字段：数据类型（数据库数据类型）
     * @param size        被追加字段：数据长度（数据库数据长度）
     * @param appendIndex 追加的列集合中的位置
     */
    public static void autoAppendField(Map colMap, JSONArray column,
                                       String prop,
                                       String label,
                                       String type, Integer size, Integer precision, Integer appendIndex) {
        if (colMap.containsKey(prop)) {
            return;
        }
        AvueBaseFormColumn columnColumn = FlyQiuAvueColTools.createColumn(prop, label, type, size, precision);
        if (appendIndex == null) {
            column.add(columnColumn.toOption());
            return;
        }
        column.add(appendIndex, columnColumn.toOption());
    }


    /**
     * 获取表单配置中全部子表单配置
     *
     * @param config 主表配置
     * @return 全部子表单配置
     */
    public static List<JSONObject> getTableAvueDynamics(FlyQiuTableConfig config) {
        JSONObject formOption = config.getFormOption();
        if (FlyQiuCollectionTools.isEmpty(formOption)) {
            return new ArrayList<>();
        }
        JSONArray column = formOption.getJSONArray("column");
        return getTableAvueDynamics(column);
    }

    /**
     * 获取表单配置中全部子表单配置
     *
     * @param columns 主表中全部列信息
     * @return 全部子表单配置
     */
    public static List<JSONObject> getTableAvueDynamics(JSONArray columns) {
        if (columns == null || columns.isEmpty()) return new ArrayList<>();
        return columns.stream().map(e -> (JSONObject) e).filter(FlyQiuAvueColTools::isDynamic).collect(Collectors.toList());
    }



    /**
     * 是否存储列数据
     *
     * @param column 列配置
     * @return boolean true 是 false 否
     */
    public static boolean isColNotStore(JSONObject column) {
        if (!column.containsKey("isStoreData")) {
            return true;
        }
        return !column.getBoolean("sqlStoreData");
    }


    /**
     * 获取列对应的组件名称
     *
     * @param col
     * @return
     */
    public static String getColumnComponentName(JSONObject col) {
        String component = col.getString("component");
        if (StringUtils.isNotBlank(component)) {
            return component;
        }
        String type = col.getString("type");
        if (StringUtils.isNotBlank(type)) {
            return type;
        }
        return "input";
    }

    /**
     * 判断给定的列对象是否为动态类型
     *
     * @param column 包含列信息的JSONObject对象
     * @return 如果列对象的类型为"dynamic"，则返回true，否则返回false
     */
    public static boolean isDynamic(JSONObject column) {
        return "dynamic".equals(column.getString("type"));
    }

    /**
     * 获取动态表单的子选项
     * <p>
     * 此方法首先判断给定的列对象是否为动态类型（通过调用isDynamic方法），
     * 如果不是动态类型，则返回null。如果列对象包含"children"键，
     * 则返回其对应的JSONObject对象，否则返回null。
     *
     * @param column 包含列信息的JSONObject对象
     * @return 如果是动态类型且包含子选项，则返回子选项的JSONObject对象，否则返回null
     */
    public static JSONObject getDynamicFormOption(JSONObject column) {
        if (!isDynamic(column)) {
            return null;
        }
        if (!column.containsKey("children")) {
            return null;
        }
        return column.getJSONObject("children");
    }

    /**
     * 获取列数据验证规则
     *
     * @param column 列配置
     * @return 验证规则
     */
    public static JSONArray getColumnRules(JSONObject column) {
        JSONArray rules = column.getJSONArray("rules");
        if (rules == null) {
            rules = new JSONArray();
        }
        boolean hasRequired = rules.stream().map(e -> (JSONObject) e).anyMatch(rule -> rule.containsKey("required") && rule.getBoolean("required"));
        if (!hasRequired && column.containsKey("required") && column.getBoolean("required")) {
            JSONObject require = new JSONObject();
            require.put("required", true);
            require.put("message", FlyQiuAvueColTools.getColumnLabel(column) + "必须填写");
            rules.add(0, require);
        }
        return rules;
    }

    /**
     * 获取列label
     *
     * @param column 列信息
     * @return label
     */
    public static String getColumnLabel(JSONObject column) {
        String label = column.getString("label");
        if (StringUtils.isAllBlank(label)) {
            return label;
        }
        return getColumnLabel(column, column.getString("prop"));
    }

    public static String getColumnLabel(JSONObject column, String defaultVal) {
        String label = column.getString("label");
        if (StringUtils.isBlank(label)) {
            return defaultVal;
        }
        return label;
    }

    public static String getColumnProp(JSONObject col) {
        if (FlyQiuCollectionTools.isEmpty(col)) {
            return null;
        }
        return col.getString("prop");

    }


    /**
     * 根据主表获取子表配置信息
     *
     * @param mainTableConfig 主表配置
     * @param dynamicCol      子表配置
     * @return 子表单配置 {@link FlyQiuTableConfig}
     */
    public static FlyQiuTableConfig getAvueDynamicFormConfig(FlyQiuTableConfig mainTableConfig, JSONObject dynamicCol) {
        FlyQiuTableConfig dynamicTable = JSONObject.from(mainTableConfig).toJavaObject(FlyQiuTableConfig.class);
        String tableName = mainTableConfig.getTableName() + "_dm_" + getColumnProp(dynamicCol);
        dynamicTable.setTableName(tableName);
        dynamicTable.setFormCode(tableName);
        dynamicTable.setFormCategory(mainTableConfig.getFormCategory());
        dynamicTable.setParentId(mainTableConfig.getId());
        String formName = mainTableConfig.getFormName() + "_" + FlyQiuAvueColTools.getColumnLabel(dynamicCol);
        dynamicTable.setFormName(formName);
        JSONObject dynamicOption = getDynamicOption(dynamicCol);
        dynamicTable.setFormOption(dynamicOption);
        dynamicTable.setId(null);
        dynamicTable.setCreateBy(null);
        dynamicTable.setCreateTime(null);
        dynamicTable.setUpdateBy(null);
        dynamicTable.setUpdateTime(null);
        dynamicTable.setTenantId(null);
        return dynamicTable;
    }

    public static JSONObject getDynamicOption(JSONObject dynamicCol) {
        if (FlyQiuCollectionTools.isEmpty(dynamicCol)) {
            return null;
        }
        return dynamicCol.getJSONObject("children");
    }


}
